From d44af6dd8f4e1dd0d858ae19419057ab4f319310 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20H=C3=A4rdeman?= Date: Thu, 9 Oct 2025 07:26:00 +0200 Subject: [PATCH] dhcpv6: create struct dhcpv6_lease MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This concludes the lease/assignment struct saga. "struct dhcp_assignment" is converted to "struct dhcpv6_lease" and various function names, etc are updated. I intentionally did *not* change variable names here to keep the patch as simple as possible. Therefore, the DHCPv6 codebase is still full of lots of variables named things like "a". I expect that to change over time when I tackle DHCPv6 code in ernest. But it'll have to do for now. Signed-off-by: David Härdeman Link: https://github.com/openwrt/odhcpd/pull/292 Signed-off-by: Álvaro Fernández Rojas --- src/config.c | 30 +++++----- src/dhcpv6-ia.c | 142 +++++++++++++++++++++++++++--------------------- src/odhcpd.h | 64 +++++++--------------- src/ubus.c | 5 +- 4 files changed, 117 insertions(+), 124 deletions(-) diff --git a/src/config.c b/src/config.c index c424266..63e3952 100644 --- a/src/config.c +++ b/src/config.c @@ -708,7 +708,7 @@ int config_set_lease_cfg_from_blobmsg(struct blob_attr *ba) lease_cfg->leasetime = time; } - INIT_LIST_HEAD(&lease_cfg->assignments); + INIT_LIST_HEAD(&lease_cfg->dhcpv6_leases); vlist_add(&lease_cfgs, &lease_cfg->node, lease_cfg); return 0; @@ -1744,18 +1744,18 @@ static int set_interface(struct uci_section *s) return config_parse_interface(blob_data(b.head), blob_len(b.head), s->e.name, true); } -static void lease_cfg_delete_dhcpv6_assignments(struct lease_cfg *lease_cfg) +static void lease_cfg_delete_dhcpv6_leases(struct lease_cfg *lease_cfg) { - struct dhcp_assignment *a, *tmp; + struct dhcpv6_lease *lease, *tmp; - list_for_each_entry_safe(a, tmp, &lease_cfg->assignments, lease_cfg_list) - free_assignment(a); + list_for_each_entry_safe(lease, tmp, &lease_cfg->dhcpv6_leases, lease_cfg_list) + dhcpv6_free_lease(lease); } -static void lease_cfg_update_assignments(struct lease_cfg *lease_cfg) +static void lease_cfg_update_leases(struct lease_cfg *lease_cfg) { struct dhcpv4_lease *a4 = lease_cfg->dhcpv4_lease; - struct dhcp_assignment *a; + struct dhcpv6_lease *lease6; if (a4) { free(a4->hostname); @@ -1765,14 +1765,14 @@ static void lease_cfg_update_assignments(struct lease_cfg *lease_cfg) a4->hostname = strdup(lease_cfg->hostname); } - list_for_each_entry(a, &lease_cfg->assignments, lease_cfg_list) { - free(a->hostname); - a->hostname = NULL; + list_for_each_entry(lease6, &lease_cfg->dhcpv6_leases, lease_cfg_list) { + free(lease6->hostname); + lease6->hostname = NULL; if (lease_cfg->hostname) - a->hostname = strdup(lease_cfg->hostname); + lease6->hostname = strdup(lease_cfg->hostname); - a->leasetime = lease_cfg->leasetime; + lease6->leasetime = lease_cfg->leasetime; } } @@ -1837,11 +1837,11 @@ static void lease_cfg_change(struct lease_cfg *lease_cfg_old, struct lease_cfg * if (lease_cfg_old->hostid != lease_cfg_new->hostid) { lease_cfg_old->hostid = lease_cfg_new->hostid; - lease_cfg_delete_dhcpv6_assignments(lease_cfg_old); + lease_cfg_delete_dhcpv6_leases(lease_cfg_old); } if (update) - lease_cfg_update_assignments(lease_cfg_old); + lease_cfg_update_leases(lease_cfg_old); free_lease_cfg(lease_cfg_new); } @@ -1849,7 +1849,7 @@ static void lease_cfg_change(struct lease_cfg *lease_cfg_old, struct lease_cfg * static void lease_cfg_delete(struct lease_cfg *lease_cfg) { dhcpv4_free_lease(lease_cfg->dhcpv4_lease); - lease_cfg_delete_dhcpv6_assignments(lease_cfg); + lease_cfg_delete_dhcpv6_leases(lease_cfg); free_lease_cfg(lease_cfg); } diff --git a/src/dhcpv6-ia.c b/src/dhcpv6-ia.c index 3046606..a7af7d0 100644 --- a/src/dhcpv6-ia.c +++ b/src/dhcpv6-ia.c @@ -41,11 +41,11 @@ (addrs)[(i)].prefix > 64) static void dhcpv6_netevent_cb(unsigned long event, struct netevent_handler_info *info); -static void apply_lease(struct dhcp_assignment *a, bool add); -static void set_border_assignment_size(struct interface *iface, struct dhcp_assignment *b); +static void apply_lease(struct dhcpv6_lease *a, bool add); +static void set_border_assignment_size(struct interface *iface, struct dhcpv6_lease *b); static void handle_addrlist_change(struct netevent_handler_info *info); -static void start_reconf(struct dhcp_assignment *a); -static void stop_reconf(struct dhcp_assignment *a); +static void start_reconf(struct dhcpv6_lease *a); +static void stop_reconf(struct dhcpv6_lease *a); static void valid_until_cb(struct uloop_timeout *event); static struct netevent_handler dhcpv6_netevent_handler = { .cb = dhcpv6_netevent_cb, }; @@ -53,6 +53,41 @@ static struct uloop_timeout valid_until_timeout = {.cb = valid_until_cb}; static uint32_t serial = 0; static uint8_t statemd5[16]; +static struct dhcpv6_lease * +dhcpv6_alloc_lease(size_t extra_len) +{ + struct dhcpv6_lease *a = calloc(1, sizeof(*a) + extra_len); + + if (!a) + return NULL; + + INIT_LIST_HEAD(&a->head); + INIT_LIST_HEAD(&a->lease_cfg_list); + + return a; +} + +void dhcpv6_free_lease(struct dhcpv6_lease *a) +{ + list_del(&a->head); + list_del(&a->lease_cfg_list); + + if (a->managed_sock.fd.registered) { + ustream_free(&a->managed_sock.stream); + close(a->managed_sock.fd.fd); + } + + if ((a->flags & OAF_BOUND) && (a->flags & OAF_DHCPV6_PD)) + apply_lease(a, false); + + if (a->fr_cnt) + stop_reconf(a); + + free(a->managed); + free(a->hostname); + free(a); +} + int dhcpv6_ia_init(void) { uloop_timeout_set(&valid_until_timeout, 1000); @@ -67,10 +102,10 @@ int dhcpv6_ia_setup_interface(struct interface *iface, bool enable) enable = enable && (iface->dhcpv6 == MODE_SERVER); if (enable) { - struct dhcp_assignment *border; + struct dhcpv6_lease *border; if (list_empty(&iface->ia_assignments)) { - border = alloc_assignment(0); + border = dhcpv6_alloc_lease(0); if (!border) { warn("Failed to alloc border on %s", iface->name); @@ -80,15 +115,15 @@ int dhcpv6_ia_setup_interface(struct interface *iface, bool enable) border->length = 64; list_add(&border->head, &iface->ia_assignments); } else - border = list_last_entry(&iface->ia_assignments, struct dhcp_assignment, head); + border = list_last_entry(&iface->ia_assignments, struct dhcpv6_lease, head); set_border_assignment_size(iface, border); } else { - struct dhcp_assignment *c; + struct dhcpv6_lease *c; while (!list_empty(&iface->ia_assignments)) { - c = list_first_entry(&iface->ia_assignments, struct dhcp_assignment, head); - free_assignment(c); + c = list_first_entry(&iface->ia_assignments, struct dhcpv6_lease, head); + dhcpv6_free_lease(c); } } @@ -113,7 +148,7 @@ static void dhcpv6_netevent_cb(unsigned long event, struct netevent_handler_info } -static inline bool valid_prefix_length(const struct dhcp_assignment *a, const uint8_t prefix_length) +static inline bool valid_prefix_length(const struct dhcpv6_lease *a, const uint8_t prefix_length) { return (a->managed_size || a->length > prefix_length); } @@ -146,7 +181,7 @@ enum { IOV_TOTAL }; -static int send_reconf(struct dhcp_assignment *assign) +static int send_reconf(struct dhcpv6_lease *assign) { struct interface *iface = assign->iface; struct dhcpv6_client_header hdr = { @@ -203,7 +238,7 @@ static int send_reconf(struct dhcp_assignment *assign) memcpy(clientid.data, assign->clid_data, assign->clid_len); - struct iovec iov[IOV_MAX] = { + struct iovec iov[IOV_TOTAL] = { [IOV_HDR] = { &hdr, sizeof(hdr) }, [IOV_SERVERID] = { &serverid, sizeof(serverid) }, [IOV_CLIENTID] = { &clientid, sizeof(clientid) }, @@ -238,22 +273,6 @@ static int send_reconf(struct dhcp_assignment *assign) return odhcpd_send(iface->dhcpv6_event.uloop.fd, &assign->peer, iov, ARRAY_SIZE(iov), iface); } -static void dhcpv6_ia_free_assignment(struct dhcp_assignment *a) -{ - if (a->managed_sock.fd.registered) { - ustream_free(&a->managed_sock.stream); - close(a->managed_sock.fd.fd); - } - - if ((a->flags & OAF_BOUND) && (a->flags & OAF_DHCPV6_PD)) - apply_lease(a, false); - - if (a->fr_cnt) - stop_reconf(a); - - free(a->managed); -} - static void in6_copy_iid(struct in6_addr *dest, uint64_t iid, unsigned n) { uint64_t iid_be = htobe64(iid); @@ -286,7 +305,7 @@ static struct in6_addr in6_from_prefix_and_iid(const struct odhcpd_ipaddr *prefi return addr; } -void dhcpv6_ia_enum_addrs(struct interface *iface, struct dhcp_assignment *c, +void dhcpv6_ia_enum_addrs(struct interface *iface, struct dhcpv6_lease *c, time_t now, dhcpv6_binding_cb_handler_t func, void *arg) { struct odhcpd_ipaddr *addrs = (c->managed) ? c->managed : iface->addr6; @@ -348,7 +367,7 @@ void dhcpv6_ia_enum_addrs(struct interface *iface, struct dhcp_assignment *c, struct write_ctxt { FILE *fp; md5_ctx_t md5; - struct dhcp_assignment *c; + struct dhcpv6_lease *c; struct interface *iface; char *buf; int buf_len; @@ -655,7 +674,7 @@ void dhcpv6_ia_write_statefile(void) } } -static void __apply_lease(struct dhcp_assignment *a, +static void __apply_lease(struct dhcpv6_lease *a, struct odhcpd_ipaddr *addrs, ssize_t addr_len, bool add) { if (a->flags & OAF_DHCPV6_NA) @@ -675,7 +694,7 @@ static void __apply_lease(struct dhcp_assignment *a, } } -static void apply_lease(struct dhcp_assignment *a, bool add) +static void apply_lease(struct dhcpv6_lease *a, bool add) { struct interface *iface = a->iface; struct odhcpd_ipaddr *addrs = (a->managed) ? a->managed : iface->addr6; @@ -685,7 +704,7 @@ static void apply_lease(struct dhcp_assignment *a, bool add) } /* Set border assignment size based on the IPv6 address prefixes */ -static void set_border_assignment_size(struct interface *iface, struct dhcp_assignment *b) +static void set_border_assignment_size(struct interface *iface, struct dhcpv6_lease *b) { time_t now = odhcpd_time(); int minprefix = -1; @@ -712,7 +731,7 @@ static void set_border_assignment_size(struct interface *iface, struct dhcp_assi static void managed_handle_pd_data(struct ustream *s, _unused int bytes_new) { struct ustream_fd *fd = container_of(s, struct ustream_fd, stream); - struct dhcp_assignment *c = container_of(fd, struct dhcp_assignment, managed_sock); + struct dhcpv6_lease *c = container_of(fd, struct dhcpv6_lease, managed_sock); time_t now = odhcpd_time(); bool first = c->managed_size < 0; @@ -776,7 +795,7 @@ static void managed_handle_pd_data(struct ustream *s, _unused int bytes_new) } if (first && c->managed_size == 0) - free_assignment(c); + dhcpv6_free_lease(c); else if (first) c->valid_until = now + 150; } @@ -786,7 +805,7 @@ static void managed_handle_pd_data(struct ustream *s, _unused int bytes_new) static void managed_handle_pd_done(struct ustream *s) { struct ustream_fd *fd = container_of(s, struct ustream_fd, stream); - struct dhcp_assignment *c = container_of(fd, struct dhcp_assignment, managed_sock); + struct dhcpv6_lease *c = container_of(fd, struct dhcpv6_lease, managed_sock); c->valid_until = odhcpd_time() + 15; @@ -796,9 +815,9 @@ static void managed_handle_pd_done(struct ustream *s) c->fr_cnt = 1; } -static bool assign_pd(struct interface *iface, struct dhcp_assignment *assign) +static bool assign_pd(struct interface *iface, struct dhcpv6_lease *assign) { - struct dhcp_assignment *c; + struct dhcpv6_lease *c; if (iface->dhcpv6_pd_manager[0]) { int fd = usock(USOCK_UNIX | USOCK_TCP, iface->dhcpv6_pd_manager, NULL); @@ -901,9 +920,9 @@ static bool is_reserved_ipv6_iid(uint64_t iid) return false; } -static bool assign_na(struct interface *iface, struct dhcp_assignment *a) +static bool assign_na(struct interface *iface, struct dhcpv6_lease *a) { - struct dhcp_assignment *c; + struct dhcpv6_lease *c; uint64_t pool_start = 0x100; uint64_t pool_end = (iface->dhcpv6_hostid_len >= 64) ? UINT64_MAX : ((1ULL << iface->dhcpv6_hostid_len) - 1); uint64_t pool_size = pool_end - pool_start + 1; @@ -955,8 +974,8 @@ static bool assign_na(struct interface *iface, struct dhcp_assignment *a) static void handle_addrlist_change(struct netevent_handler_info *info) { struct interface *iface = info->iface; - struct dhcp_assignment *c, *d, *border = list_last_entry( - &iface->ia_assignments, struct dhcp_assignment, head); + struct dhcpv6_lease *c, *d, *border = list_last_entry( + &iface->ia_assignments, struct dhcpv6_lease, head); struct list_head reassign = LIST_HEAD_INIT(reassign); time_t now = odhcpd_time(); @@ -982,7 +1001,7 @@ static void handle_addrlist_change(struct netevent_handler_info *info) apply_lease(c, true); if (c->accept_fr_nonce && c->fr_cnt == 0) { - struct dhcp_assignment *a; + struct dhcpv6_lease *a; start_reconf(c); @@ -995,10 +1014,10 @@ static void handle_addrlist_change(struct netevent_handler_info *info) } while (!list_empty(&reassign)) { - c = list_first_entry(&reassign, struct dhcp_assignment, head); + c = list_first_entry(&reassign, struct dhcpv6_lease, head); list_del_init(&c->head); if (!assign_pd(iface, c)) - free_assignment(c); + dhcpv6_free_lease(c); } dhcpv6_ia_write_statefile(); @@ -1006,7 +1025,7 @@ static void handle_addrlist_change(struct netevent_handler_info *info) static void reconf_timeout_cb(struct uloop_timeout *event) { - struct dhcp_assignment *a = container_of(event, struct dhcp_assignment, fr_timer); + struct dhcpv6_lease *a = container_of(event, struct dhcpv6_lease, fr_timer); if (a->fr_cnt > 0 && a->fr_cnt < DHCPV6_REC_MAX_RC) { send_reconf(a); @@ -1017,7 +1036,7 @@ static void reconf_timeout_cb(struct uloop_timeout *event) stop_reconf(a); } -static void start_reconf(struct dhcp_assignment *a) +static void start_reconf(struct dhcpv6_lease *a) { uloop_timeout_set(&a->fr_timer, DHCPV6_REC_TIMEOUT << a->fr_cnt); @@ -1027,7 +1046,7 @@ static void start_reconf(struct dhcp_assignment *a) send_reconf(a); } -static void stop_reconf(struct dhcp_assignment *a) +static void stop_reconf(struct dhcpv6_lease *a) { uloop_timeout_cancel(&a->fr_timer); a->fr_cnt = 0; @@ -1040,21 +1059,21 @@ static void valid_until_cb(struct uloop_timeout *event) time_t now = odhcpd_time(); avl_for_each_element(&interfaces, iface, avl) { - struct dhcp_assignment *a, *n; + struct dhcpv6_lease *a, *n; if (iface->dhcpv6 != MODE_SERVER) continue; list_for_each_entry_safe(a, n, &iface->ia_assignments, head) { if (a->clid_len > 0 && !INFINITE_VALID(a->valid_until) && a->valid_until < now) - free_assignment(a); + dhcpv6_free_lease(a); } } uloop_timeout_set(event, 1000); } static size_t build_ia(uint8_t *buf, size_t buflen, uint16_t status, - const struct dhcpv6_ia_hdr *ia, struct dhcp_assignment *a, + const struct dhcpv6_ia_hdr *ia, struct dhcpv6_lease *a, struct interface *iface, bool request) { struct dhcpv6_ia_hdr o_ia = { @@ -1329,7 +1348,7 @@ static void dhcpv6_log_ia_addr(struct in6_addr *addr, int prefix, _unused uint32 } static void dhcpv6_log(uint8_t msgtype, struct interface *iface, time_t now, - const char *duidbuf, bool is_pd, struct dhcp_assignment *a, int code) + const char *duidbuf, bool is_pd, struct dhcpv6_lease *a, int code) { const char *type = "UNKNOWN"; const char *status = "UNKNOWN"; @@ -1390,7 +1409,7 @@ static void dhcpv6_log(uint8_t msgtype, struct interface *iface, time_t now, duidbuf, iface->name, status, leasebuf); } -static bool dhcpv6_ia_on_link(const struct dhcpv6_ia_hdr *ia, struct dhcp_assignment *a, +static bool dhcpv6_ia_on_link(const struct dhcpv6_ia_hdr *ia, struct dhcpv6_lease *a, struct interface *iface) { struct odhcpd_ipaddr *addrs = (a && a->managed) ? a->managed : iface->addr6; @@ -1437,7 +1456,7 @@ static bool dhcpv6_ia_on_link(const struct dhcpv6_ia_hdr *ia, struct dhcp_assign ssize_t dhcpv6_ia_handle_IAs(uint8_t *buf, size_t buflen, struct interface *iface, const struct sockaddr_in6 *addr, const void *data, const uint8_t *end) { - struct dhcp_assignment *first = NULL; + struct dhcpv6_lease *first = NULL; const struct dhcpv6_client_header *hdr = data; time_t now = odhcpd_time(); uint16_t otype, olen, clid_len = 0; @@ -1548,7 +1567,7 @@ ssize_t dhcpv6_ia_handle_IAs(uint8_t *buf, size_t buflen, struct interface *ifac } /* Find an existing assignment */ - struct dhcp_assignment *c, *a = NULL; + struct dhcpv6_lease *c, *a = NULL; list_for_each_entry(c, &iface->ia_assignments, head) { /* If we're looking for a PD, is this a PD? */ if (is_pd && !(c->flags & OAF_DHCPV6_PD)) @@ -1598,7 +1617,7 @@ ssize_t dhcpv6_ia_handle_IAs(uint8_t *buf, size_t buflen, struct interface *ifac * already knows or doesn't care about the old assignment. */ stop_reconf(c); - free_assignment(c); + dhcpv6_free_lease(c); goto proceed; } continue; @@ -1616,7 +1635,7 @@ ssize_t dhcpv6_ia_handle_IAs(uint8_t *buf, size_t buflen, struct interface *ifac } if (lease_cfg && a && a->lease_cfg != lease_cfg) { - free_assignment(a); + dhcpv6_free_lease(a); a = NULL; } @@ -1635,7 +1654,7 @@ proceed: if ((!iface->no_dynamic_dhcp || (lease_cfg && is_na)) && (iface->dhcpv6_pd || iface->dhcpv6_na)) { /* Create new binding */ - a = alloc_assignment(clid_len); + a = dhcpv6_alloc_lease(clid_len); if (a) { a->clid_len = clid_len; @@ -1649,7 +1668,6 @@ proceed: a->assigned_subnet_id = reqhint; a->valid_until = now; a->preferred_until = now; - a->dhcp_free_cb = dhcpv6_ia_free_assignment; a->iface = iface; a->flags = (is_pd ? OAF_DHCPV6_PD : OAF_DHCPV6_NA); @@ -1673,7 +1691,7 @@ proceed: if (lease_cfg->leasetime) a->leasetime = lease_cfg->leasetime; - list_add(&a->lease_cfg_list, &lease_cfg->assignments); + list_add(&a->lease_cfg_list, &lease_cfg->dhcpv6_leases); a->lease_cfg = lease_cfg; } @@ -1753,7 +1771,7 @@ proceed: apply_lease(a, true); } else if (!assigned && a && a->managed_size == 0) { /* Cleanup failed assignment */ - free_assignment(a); + dhcpv6_free_lease(a); a = NULL; } } else if (hdr->msg_type == DHCPV6_MSG_RENEW || diff --git a/src/odhcpd.h b/src/odhcpd.h index 395cee5..41c0099 100644 --- a/src/odhcpd.h +++ b/src/odhcpd.h @@ -251,27 +251,10 @@ struct dhcpv4_lease { struct odhcpd_ref_ip *fr_ip; // FR message old serverid/IP }; -/* This corresponds to a UCI host section, i.e. a static lease cfg */ -struct lease_cfg { - struct vlist_node node; - struct list_head assignments; - struct dhcpv4_lease *dhcpv4_lease; - uint32_t ipaddr; - uint64_t hostid; - size_t mac_count; - struct ether_addr *macs; - size_t duid_count; - struct duid *duids; - uint32_t leasetime; // duration of granted leases, UINT32_MAX = inf - char *hostname; -}; - -struct dhcp_assignment { +struct dhcpv6_lease { struct list_head head; struct list_head lease_cfg_list; - void (*dhcp_free_cb)(struct dhcp_assignment *a); - struct interface *iface; struct lease_cfg *lease_cfg; @@ -304,6 +287,21 @@ struct dhcp_assignment { uint8_t clid_data[]; }; +/* This corresponds to a UCI host section, i.e. a static lease cfg */ +struct lease_cfg { + struct vlist_node node; + struct list_head dhcpv6_leases; + struct dhcpv4_lease *dhcpv4_lease; + uint32_t ipaddr; + uint64_t hostid; + size_t mac_count; + struct ether_addr *macs; + size_t duid_count; + struct duid *duids; + uint32_t leasetime; // duration of granted leases, UINT32_MAX = inf + char *hostname; +}; + // DNR - RFC9463 struct dnr_options { uint16_t priority; @@ -487,31 +485,6 @@ enum { }; extern const struct blobmsg_policy lease_cfg_attrs[LEASE_CFG_ATTR_MAX]; -inline static void free_assignment(struct dhcp_assignment *a) -{ - list_del(&a->head); - list_del(&a->lease_cfg_list); - - if (a->dhcp_free_cb) - a->dhcp_free_cb(a); - - free(a->hostname); - free(a); -} - -inline static struct dhcp_assignment *alloc_assignment(size_t extra_len) -{ - struct dhcp_assignment *a = calloc(1, sizeof(*a) + extra_len); - - if (!a) - return NULL; - - INIT_LIST_HEAD(&a->head); - INIT_LIST_HEAD(&a->lease_cfg_list); - - return a; -} - inline static bool ra_pio_expired(const struct ra_pio *pio, time_t now) { return pio->lifetime && (now > pio->lifetime); @@ -611,8 +584,9 @@ ssize_t dhcpv6_ia_handle_IAs(uint8_t *buf, size_t buflen, struct interface *ifac const struct sockaddr_in6 *addr, const void *data, const uint8_t *end); int dhcpv6_ia_init(void); int dhcpv6_ia_setup_interface(struct interface *iface, bool enable); -void dhcpv6_ia_enum_addrs(struct interface *iface, struct dhcp_assignment *c, time_t now, - dhcpv6_binding_cb_handler_t func, void *arg); +void dhcpv6_free_lease(struct dhcpv6_lease *lease); +void dhcpv6_ia_enum_addrs(struct interface *iface, struct dhcpv6_lease *lease, + time_t now, dhcpv6_binding_cb_handler_t func, void *arg); void dhcpv6_ia_write_statefile(void); int netlink_add_netevent_handler(struct netevent_handler *hdlr); diff --git a/src/ubus.c b/src/ubus.c index f1ce074..4b31e1a 100644 --- a/src/ubus.c +++ b/src/ubus.c @@ -120,8 +120,9 @@ static int handle_dhcpv6_leases(_unused struct ubus_context *ctx, _unused struct void *i = blobmsg_open_table(&b, iface->ifname); void *j = blobmsg_open_array(&b, "leases"); - struct dhcp_assignment *a, *border = list_last_entry( - &iface->ia_assignments, struct dhcp_assignment, head); + struct dhcpv6_lease *a, *border; + + border = list_last_entry(&iface->ia_assignments, struct dhcpv6_lease, head); list_for_each_entry(a, &iface->ia_assignments, head) { if (a == border || (!INFINITE_VALID(a->valid_until) && -- 2.30.2